package com.scalar.chiptrack.adaptor.utac;

import com.scalar.chiptrack.adaptor.AdaptorConstants;
import com.scalar.chiptrack.adaptor.AdaptorUtils;
import com.scalar.chiptrack.adaptor.FabSortLot;
import com.scalar.chiptrack.adaptor.dao.FabSortAdaptorDAO;
import com.scalar.chiptrack.adaptor.dao.AdaptorRunInfo;
import com.scalar.chiptrack.jobs.JobHandler;
import com.scalar.chiptrack.utils.Logger;
import com.scalar.ScalarException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.io.File;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

/**
 * User: ChandraSekhar
 * Date: Jan 17, 2008
 * Time: 4:52:28 PM
 */
public class UTACFTPDataParser extends JobHandler implements AdaptorConstants
{
    HashMap m_sortBinDataMap    = new HashMap();

    int m_waferidCount            = 0;
    int m_totalQtyIn              = 0;
    int m_totalQtyOut             = 0;
    float m_totalYield            = 0.0f;

    private Logger m_parserLogger = null;
    private String m_dataOutputDir = null;

    public UTACFTPDataParser() throws ScalarException
    {
        try
        {
            m_dataOutputDir = AdaptorUtils.getDataOutputDir(VENDOR_NAME_UTAC_SING , WIP_TYPE_SORT);
            AdaptorUtils.makeAllAdaptorDirs(m_dataOutputDir);
            m_parserLogger = AdaptorUtils.getDataParserLogger(m_dataOutputDir,VENDOR_NAME_UTAC_SING);
            FabSortAdaptorDAO.setLogger(m_parserLogger);
            AdaptorUtils.setLogger( m_parserLogger );
        }
        catch ( ScalarException se )
        {
            System.out.println( "ERROR!! ERROR!! ERROR!! Could not create get the logger to log UTAC FTP Data Parser activity, Exception: " + se );
            throw se;
        }
    }

    public static void main( String args[] ) throws Exception
    {
        try
        {
            new UTACFTPDataParser().execute();
        }
        catch ( Exception e )
        {
            throw e;
        }
    }

    public void execute() throws Exception
    {
        AdaptorUtils.printHeader("UTAC SING SORT FTP", CONSTANT_PARSER );

        File doneDestDir = new File(m_dataOutputDir + "/done");

       File wipDataoutDir = new File(m_dataOutputDir);


       File[] fileList = wipDataoutDir.listFiles();

       if ((fileList == null) || (fileList.length <= 3))
       {
           log("No file found in directory: " + wipDataoutDir);
           throw new ScalarException("No file found in directory: " + wipDataoutDir + "----\n\n");
       }

        int adaptor_id = AdaptorRunInfo.getLastRunAdaptorId( UTACFTPAdaptor.ADAPTOR_NAME, CONSTANT_ADAPTOR);

        ArrayList sortlotbinList    = null;
        ArrayList successFileList   = new ArrayList();
        boolean success             = false;

        for (int i = 0; i < fileList.length; i++)
        {
            if ( fileList[i].isDirectory() == true )
            {
                continue;
            }

            try
            {
                // Step 1
                // Parse Files to get Object List
                if ( fileList[i].getName().startsWith( UTACFTPAdaptor.FILE_NAME_SORT_WIP ) )
                {
                    sortlotbinList = parseSortLotBinReport( fileList[i].getAbsolutePath() );

                    //To get the Sort Binning information
                    getSortBinDetails( sortlotbinList );
                    m_waferidCount = 0;
                    successFileList.add( fileList[i] );
                }
                success = true;
            }
            catch ( Exception e )
            {
                AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, adaptor_id );
                success = false;
                log( "Exception while parsing and storing file: " + fileList[i].getAbsolutePath() + "\nException: " + e );
                e.printStackTrace();
                throw e;
            }
        }

        try
        {
            if ( m_sortBinDataMap.isEmpty() == false )
            {
                FabSortAdaptorDAO.saveSortBinData( null, m_sortBinDataMap.values().iterator() );
            }
            success = true;
            m_sortBinDataMap.clear();
        }
        catch(Exception e)
        {
            AdaptorRunInfo.updatedAdaptorStatus( CONSTANT_FAILURE, adaptor_id );
            success = false;
            System.out.println(" Exception Occrred While Saving the Sort Binning Info " +e );
            throw e;
        }

       // Update Adaptor_Run_Info table
        try
        {
            if ( success == true )
            {
                AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, UTACFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
                System.out.println( "SUCCESSFULLY UPDATED IN THE DATABASE" );
            }
        }
        catch ( ScalarException se )
        {
            success = false; //As filES DATA SAVED , UPDATEING AS SUCCESS
            AdaptorRunInfo.saveAdaptorLastUpdatedStatus(CONSTANT_PARSER, UTACFTPAdaptor.ADAPTOR_NAME, CONSTANT_SUCCESS, adaptor_id);
            log( "WARNING!! WARNING!! WARNING!! Could not update Adaptor run information, Exception: " + se );
            throw se;
        }

       // Move the successful files to 'done' directory
       if ( success )
       {
           AdaptorUtils.moveFilesToDone( successFileList, doneDestDir );
       }
    } // end of execute method.


    /**
     * Reads, parses the file
     */
    private ArrayList parseSortLotBinReport( String fileName ) throws Exception
    {
        ArrayList lotbinList = new ArrayList();
        UTACSortBinReport sortBinReport = null;
        if ( fileName == null ) throw new ScalarException( "Filename argument is null" );

        // Phase-I variables
        File lotbinFile = new File( fileName );
        if ( lotbinFile.exists() == false )
        {
            throw new ScalarException( fileName + " doesnt exist" );
        }

        String DEVICE   = "Device        :";
        String LOTNO    = "Lot ID        :";
        //String testMode = "Test Mode     :";
        //String testerID = "Tester ID     :";
        String DATE     = "Date          :";
        String SORT_QTY_IN = "TotalIn :";
        String deviceName = null;
        String lotNo = null;
        String dateIn = null;
        String line = null;

        BufferedReader bReader = null;
        try
        {
            bReader = new BufferedReader( new FileReader( lotbinFile ) );

            while ( ( line = bReader.readLine() ) != null  )
            {
                line = line.trim();

                if ( line.length() < 65 )
                {
                    if ( line.indexOf( DEVICE ) != -1 )
                    {
                        deviceName = line.substring( DEVICE.length() ).trim();
                    }
                    if ( line.indexOf( LOTNO ) != -1 )
                    {
                        lotNo = line.substring( LOTNO.length() ).trim();
                    }
                    if ( line.indexOf( DATE ) != -1 )
                    {
                        dateIn = line.substring( DATE.length() ).trim();
                    }
                    if ( line.indexOf( SORT_QTY_IN ) != -1 )
                    {
                        int index = line.indexOf( "TotalOut" );
                        int index1 = line.indexOf( "AverageYield" );
                        
                        m_totalQtyIn = Integer.parseInt( line.substring( SORT_QTY_IN.length(), index ).trim() );
                        m_totalQtyOut = Integer.parseInt( line.substring( index + 10, index1 ).trim() );
                        m_totalYield = Float.parseFloat( line.substring( index1 + 15, index1 + 21 ).trim() );
                    }
                }
            }
            bReader.close();
            bReader = null;
            line = null;


            int rejectedQty     = 0;
            bReader = new BufferedReader( new FileReader( lotbinFile ) );

            while ( ( line = bReader.readLine() ) != null  )
            {
                line = line.trim();
                if ( ( !line.startsWith( "Slt" ) ) && ( !line.startsWith( "------" ) ) && line.length() > 75 )
                {
                    sortBinReport = new UTACSortBinReport();

                    int waferId = Integer.parseInt( line.substring( 0, 2 ).trim() );

                    int waferDieQtyIn  = Integer.parseInt(line.substring(3, 8).trim());
                    int waferDieQtyOut = Integer.parseInt(line.substring(9, 14).trim() ); //BIN1 QTY
                    float waferYield     = Float.parseFloat(line.substring(15, 20).trim());

                    rejectedQty =  waferDieQtyIn - waferDieQtyOut;

                    if( lotNo != null && deviceName != null && waferId > 0 && waferId < 26 )
                    {
                        sortBinReport.setWaferId( waferId +"" );
                        sortBinReport.setGoodBinQty( waferDieQtyOut );
                        sortBinReport.setDeviceName( deviceName );
                        sortBinReport.setDateIn( dateIn );
                        sortBinReport.setLotNumber( lotNo );
                        sortBinReport.setRejectedQty( rejectedQty );
                        sortBinReport.setWaferYield( waferYield );

                        m_waferidCount++;
                        lotbinList.add(sortBinReport);
                    }
                }
            }

        }
        catch ( Exception e )
        {
            System.out.println( "Exception while parsing UTAC SING Sort Bin information \n" + e + "\n" );
            throw e;
        }
        finally
        {
            if ( bReader != null )
            {
                try
                {
                    bReader.close();
                }
                catch ( IOException ignore )
                {
                }
            }
        }
        return lotbinList;
    } // end of prase sortLot bin report method

    private void getSortBinDetails( ArrayList sortBinList )  throws Exception
    {
        if ( sortBinList == null || sortBinList.size() == 0 )
        {
           log( "No Sort Bin Lots when the List is Empty");
           return;
        }
        UTACSortBinReport sortbinReport  = null;
        String partNumber                = null;
        String lotNumber                 = null;
        String waferId                   = null;
        FabSortLot sortBinLot            = null;

        try
        {
            Iterator iterator = sortBinList.iterator();

            while ( iterator.hasNext() )
            {
                sortbinReport = ( UTACSortBinReport )iterator.next() ;

                lotNumber  = sortbinReport.getLotNumber();
                waferId    = sortbinReport.getWaferId();
                partNumber = sortbinReport.getDeviceName();

                if ( partNumber != null && lotNumber != null && waferId != null )
                {
                    sortBinLot = ( FabSortLot ) m_sortBinDataMap.get( partNumber + lotNumber + waferId );

                    if ( sortBinLot == null )
                    {
                        sortBinLot = new FabSortLot( VENDOR_NAME_UTAC_SING , LOCATION_TYPE_SORT );
                        m_sortBinDataMap.put( partNumber + lotNumber + waferId , sortBinLot );
                    }

                    sortBinLot.setCustProduct( partNumber );
                    sortBinLot.setLotId( lotNumber );
                    sortBinLot.setWaferID( waferId );
                    // WAFER QTY IN Always Same(total wafers) ,But For Each every Wafer update the Wafer Qty, the the WaferQty
                    sortBinLot.setQtyIn( m_waferidCount +"" );
                    sortBinLot.setDateIn( sortbinReport.getDateIn() );
                    sortBinLot.setTotalgoodDieQtyIn( m_totalQtyOut );
                    sortBinLot.setTotalprobeQtyIn( m_totalQtyIn );
                    sortBinLot.setGoodDieQtyIn(sortbinReport.getGoodBinQty());
                    sortBinLot.setRejectedQtyIn(sortbinReport.getRejectedQty());
                    sortBinLot.setShipYield(sortbinReport.getWaferYield()+"");
                    sortBinLot.setTotalYield( m_totalYield ); // if sets as 0, in the PROC Yield Calculating (INQTY *100.00/OUTQTY)
                    sortBinLot.setBinNumber( "Bin1");
                }
            }
        }
        catch(Exception e )
        {
            throw new ScalarException("Exception occured while parsing the Sort Bin Inforamtion" +e );
        }
    }

    private void log( String message )
    {
        if ( message == null ) return;

        if ( m_parserLogger != null )
        {
            m_parserLogger.logDebug( message + LINE_SEPARATOR );
        }
        else
        {
            System.out.println( message );
        }
    } // end of log method
}

